package edu.iu.criminfo.voronoi.object;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import edu.iu.criminfo.voronoi.gpsUtils.Distance;
import edu.iu.criminfo.voronoi.kmeans.Cluster;

public class Point {
	public double coordinateX;
	public double coordinateY;
	
	public Point() {
		this.coordinateX = 0;
		this.coordinateY = 0;
	}

	public Point(double coordinateX, double coordinateY) {
		this.coordinateX = coordinateX;
		this.coordinateY = coordinateY;
	}

	public int inWhichCluster(List<Cluster> clusterList) {
		int index = -1;
		double minimumDistance = -1;
		
		int i = 0;
		for (Cluster cluster: clusterList) {
			double distance = distance(cluster.getCenter());
			if ((index < 0) || (distance < minimumDistance)) {
				minimumDistance = distance;
				index = i; 
			}			
			i++;
		}
		
		return index;
	}
	
	public int inWitchCluster(List<Cluster> clusterList, double alpha, double capacity) {
		int index = -1;
		double minimumDistance = -1;
		List<Double> doubleList = new ArrayList<Double>();
		
		int i = 0;
		for (Cluster cluster: clusterList) {
			double distance = alpha * distance(cluster.getCenter());
			if ((index < 0) || (distance < minimumDistance)) {
				minimumDistance = distance;
				index = i; 
			}
			distance = distance + cluster.size() * (1-alpha);
			doubleList.add(new Double(distance));
			i++;
		}
		
		if (clusterList.get(index).size() < capacity) {
			return index;
		}
		else {
			List<Double> sourceList = new ArrayList<Double>();
			for (Double distance: doubleList) {
				sourceList.add(new Double(distance.doubleValue()));
			}
			
			Collections.sort(doubleList);
			
			for (Double distance: doubleList) {
				i = 0;
				for (Double sourceDist: sourceList) {
					if (sourceDist.doubleValue() == distance.doubleValue()) {
						break;
					}
					i++;
				}
				if (clusterList.get(i).size() >= capacity) {
					continue;
				}
				else {
					index = i;
					return index;
				}
			}
		}
		return -1;
	}

	/*public double distance(final Point dest) {
		return Math.sqrt((dest.coordinateY - coordinateY)
				* (dest.coordinateY - coordinateY)
				+ (dest.coordinateX - coordinateX)
				* (dest.coordinateX - coordinateX));
	}*/
	
	public double distance(final Point dest) {
		return Distance.getDistance(coordinateX, coordinateY, dest.coordinateX, dest.coordinateY);
	}
}
